﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows.Forms;

namespace CSharpHelpers.Winforms
{
    class ControlHelper
    {
        #region 根据字段名称返回值
        /// <summary>
        /// 根据字段名称返回值
        /// @author john add by 2013-7-15
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="fieldname"></param>
        /// <returns></returns>
        public static object GetValueByFieldName(object obj, string fieldname)
        {
            PropertyInfo[] properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            for (int i = 0; i < properties.Length; i++)
            {
                if (properties[i].Name == fieldname)
                {
                    return properties[i].GetValue(obj, null);
                }
            }
            return null;
        }
        #endregion

        #region 根据控件名称获得字段名称
        /// <summary>
        /// 根据控件名称获得字段名称
        /// @author john add by 2013-7-15
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public static string GetFieldByControlName(Control control)
        {
            string field = string.Empty;
            if (!string.IsNullOrEmpty(control.Name))
            {
                field = control.Name.Substring(3, control.Name.Length - 3);
            }
            return field;
        }
        #endregion

        #region 给Windows控件赋值
        /// <summary>
        /// 给窗体的Windows控件赋值
        /// @author john add by 2013-7-15
        /// </summary>
        /// <param name="form">源窗体From</param>
        /// <param name="entity">实体</param>
        public static void SetFormControlValue(Form form, object entity)
        {
            foreach (Control ctrl in form.Controls)
            {
                SetControlValue(ctrl, entity);
            }
        }

        /// <summary>
        /// 给Windows控件赋值
        /// @author john add by 2013-7-15
        /// </summary>
        /// <param name="ctrl"></param>
        /// <param name="entity"></param>
        public static void SetControlValue(Control ctrl, object entity)
        {
            if (ctrl.Name != null && !(ctrl is DataGridView))
            {
                if (ctrl.HasChildren)
                {
                    foreach (Control con in ctrl.Controls)
                    {
                        SetControlValue(con, entity);
                    }
                }

                object fieldValue = GetValueByFieldName(entity, GetFieldByControlName(ctrl));
                if (fieldValue != null)
                {
                    //if (ctrl is Label)
                    //{
                    //    if (fieldValue.GetType() == typeof(DateTime))
                    //    {
                    //        ((Label)ctrl).Text = fieldValue == null ? "" : DateTime.Parse(fieldValue.ToString()).ToString("yyyy-MM-dd");
                    //    }
                    //    else
                    //    {
                    //        ((Label)ctrl).Text = fieldValue.ToString();
                    //    }
                    //}

                    if (ctrl is TextBox)
                    {
                        if (fieldValue.GetType() == typeof(DateTime))
                        {
                            ((TextBox)ctrl).Text = fieldValue == null ? "" : DateTime.Parse(fieldValue.ToString()).ToString("yyyy-MM-dd");
                        }
                        else
                        {
                            ((TextBox)ctrl).Text = fieldValue.ToString();
                        }
                    }
                    else if (ctrl is ComboBox)
                    {
                        ComboBox cbx = (ComboBox)ctrl;
                        var type = fieldValue.GetType();
                        if (type.IsEnum)
                        {
                            fieldValue = (int)fieldValue;
                            cbx.SelectedValue = fieldValue;
                        }
                        else
                        {
                            cbx.SelectedValue = fieldValue;
                        }

                    }
                    else if (ctrl is CheckBox)
                    {
                        CheckBox chk = (CheckBox)ctrl;
                        //chk.Checked = (bool)fieldValue;
                        // Convert.ToBoolean 可以將1轉為 true
                        chk.Checked = Convert.ToBoolean(fieldValue);
                    }
                    else if (ctrl is DateTimePicker)
                    {
                        DateTimePicker dtp = (DateTimePicker)ctrl;
                        dtp.Value = CoverToDateTime(fieldValue);
                    }
                    else if (ctrl is RichTextBox)
                    {
                        ctrl.Text = fieldValue.ToString();
                    }
                }
            }
        }

        /// <summary>
        /// 將obj 轉為 DateTime 如果datetime等於 0001-01-01 無效日期則賦值1900-01-01
        /// @author Bell add by 2013-7-15
        /// </summary>
        /// <param name="obj">被轉的obj</param>
        /// <returns>返回日期</returns>
        private static DateTime CoverToDateTime(object obj)
        {
            DateTime day = new DateTime(1900, 1, 1);
            if (obj != null)
            {
                DateTime.TryParse(obj.ToString(), out day);
            }

            if (day == new DateTime())
            {
                day = new DateTime(1900, 1, 1);
            }

            return day;
        }

        #endregion

        #region 给实体对象赋值
        /// <summary>
        /// 给实体对象赋值
        /// @author john add by 2013-7-15
        /// </summary>
        public static void SetObjectValue(Control form, object obj)
        {
            foreach (Control ctrl in form.Controls)
            {
                if (ctrl.HasChildren && !(ctrl is DataGridView))
                {
                    SetObjectValue(ctrl, obj);
                }

                if (ctrl.Name != null)
                {
                    if (ctrl is TextBox || ctrl is RichTextBox)
                    {
                        SetProperty(obj, GetFieldByControlName(ctrl), GetProperty(ctrl, "Text"));
                    }
                    else if (ctrl is ComboBox)
                    {
                        SetProperty(obj, GetFieldByControlName(ctrl), GetProperty(ctrl, "SelectedValue"));
                    }
                    else if (ctrl is CheckBox)
                    {
                        SetProperty(obj, GetFieldByControlName(ctrl), GetProperty(ctrl, "Checked"));
                    }
                    else if (ctrl is DateTimePicker)
                    {
                        SetProperty(obj, GetFieldByControlName(ctrl), GetProperty(ctrl, "Value"));
                    }
                }
            }
        }
        #endregion

        #region 获取对象属性的值
        /// <summary> 
        /// 获取对象属性的值
        /// @author john add by 2013-7-15
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static object GetProperty(object obj, string name)
        {
            PropertyInfo propertyInfo = obj.GetType().GetProperty(name);
            return propertyInfo.GetValue(obj, null);
        }
        #endregion

        #region 设置对象属性的值
        /// <summary>
        /// 设置对象属性的值
        /// @author john add by 2013-7-15
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public static void SetProperty(object obj, string name, object value)
        {
            PropertyInfo propertyInfo = obj.GetType().GetProperty(name);
            if (propertyInfo == null)
            {
                return;
            }
            if (propertyInfo.PropertyType == typeof(String))
            {
                var objValue = Convert.ChangeType(value, propertyInfo.PropertyType);
                propertyInfo.SetValue(obj, objValue, null);
            }
            else if (propertyInfo.PropertyType == typeof(Boolean))
            {
                bool objValue = (bool)value;
                propertyInfo.SetValue(obj, objValue, null);
            }
            else if (propertyInfo.PropertyType == typeof(Int32) && value != null)
            {
                // Convert.ToInt32 可以將true 轉為1   false 轉為0 
                //Int32 objValue = value.ToString().Trim() == "" ? 0 : Int32.Parse(value.ToString().Trim());

                Int32 objValue = value.ToString().Trim() == "" ? 0 : Convert.ToInt32(value);
                propertyInfo.SetValue(obj, objValue, null);
            }
            else if (propertyInfo.PropertyType == typeof(DateTime))
            {
                DateTime objValue = (DateTime)value;
                propertyInfo.SetValue(obj, objValue, null);
            }
            else if (propertyInfo.PropertyType == typeof(Double))
            {
                Double objValue = Convert.ToDouble(value);
                propertyInfo.SetValue(obj, objValue, null);
            }
            else if (propertyInfo.PropertyType.BaseType == typeof(Enum))
            {
                propertyInfo.SetValue(obj, value, null);
            }
        }
        #endregion

        #region 根据值绑定CheckedListBox

        /// <summary>
        /// 绑定CheckedListBox
        /// </summary>
        /// <param name="box"></param>
        /// <param name="dic"></param>
        public static void BindCheckedListBox(CheckedListBox box, Dictionary<int, string> dic)
        {
            if (dic.Count != 0)
            {
                BindingSource bs = new BindingSource();
                bs.DataSource = dic;
                box.DataSource = bs;
                box.DisplayMember = "Value";
                box.ValueMember = "Key";
            }
        }

        /// <summary>
        /// 给CheckedListBox赋值
        /// </summary>
        /// <param name="box"></param>
        /// <param name="values"></param>
        public static void BindCheckedListBox(CheckedListBox box, string values = "")
        {
            bool isChecked = false;

            for (int i = 0; i < box.Items.Count; i++)
            {
                KeyValuePair<int, string> pair = (KeyValuePair<int, string>)box.Items[i];
                string value = "," + pair.Key.ToString() + ",";

                values = "," + values + ",";
                if (values.Contains(value))
                {
                    isChecked = true;
                }
                else
                {
                    isChecked = false;
                }

                box.SetItemChecked(i, isChecked);
            }
        }
        #endregion

        #region 获得已勾选的值，并连接成字符串
        /// <summary>
        ///  获得已勾选的值，并连接成字符串
        /// </summary>
        /// <param name="box"></param>
        /// <returns></returns>
        public static string GetCheckedListBoxByValues(CheckedListBox box)
        {
            string str = string.Empty;
            for (int i = 0; i < box.CheckedItems.Count; i++)
            {
                KeyValuePair<string, string> items = (KeyValuePair<string, string>)box.CheckedItems[i];
                str += items.Value + ",";
            }
            if (str != String.Empty)
            {
                str = str.Substring(0, str.Length - 1);
            }
            return str;
        }
        #endregion

        #region 获得已勾选的，并增加到list里
        /// <summary>
        ///  获得已勾选的，并增加到list里
        /// </summary>
        /// <param name="box"></param>
        /// <returns></returns>
        public static List<string> GetCheckedListBoxKey(CheckedListBox box)
        {
            List<string> listValue = new List<string>();

            for (int i = 0; i < box.CheckedItems.Count; i++)
            {
                KeyValuePair<int, string> items = (KeyValuePair<int, string>)box.CheckedItems[i];
                listValue.Add(items.Key.ToString());
            }
            return listValue;
        }
        #endregion
    }
}
